#include <iostream>
#include <thread>
#include <chrono>
#include "threadpool.h"

using uLong = unsigned long long;

class MyTask : public Task
{
public:
    MyTask(uLong begin, uLong end)
        : begin_(begin)
        , end_(end)
    {}
    Any run()
    {
        std::cout << "begin: " << std::this_thread::get_id() << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(3));
        uLong sum = 0;
        for (uLong i = begin_; i <= end_; i++) sum += i;
        std::cout << "end: " << std::this_thread::get_id() << std::endl;
        return sum;
    }
private:
    uLong begin_;
    uLong end_; 
};

int main()
{
    {    
        ThreadPool pool;
        pool.setMode(PoolMode::MODE_CACHED);
        pool.start(2);
        Result ret = pool.submitTask(std::make_shared<MyTask>(1, (uLong)10000000));
        Result ret2 = pool.submitTask(std::make_shared<MyTask>(1, (uLong)10000000));
        pool.submitTask(std::make_shared<MyTask>(1, (uLong)10000000));
        pool.submitTask(std::make_shared<MyTask>(1, (uLong)10000000));
        pool.submitTask(std::make_shared<MyTask>(1, (uLong)10000000));
        uLong s1 = ret.get().cast_<uLong>();
        // uLong s2 = ret2.get().cast_<uLong>();
        std::cout << s1 << "\n";
        // std::cout << s2 << "\n";
    }
    std::cout << "main thread exit!\n";
    getchar();
    return 0;
}

#if 0
int main()
{
    ThreadPool pool;
    pool.setMode(PoolMode::MODE_CACHED);
    pool.start(4);
    Result r1 = pool.submitTask(std::make_shared<MyTask>(1, (uLong)10000000));
    Result r2 = pool.submitTask(std::make_shared<MyTask>((uLong)10000001, (uLong)20000000));
    Result r3 = pool.submitTask(std::make_shared<MyTask>((uLong)20000001, (uLong)30000000));
    pool.submitTask(std::make_shared<MyTask>((uLong)20000001, (uLong)30000000));
    
    // 创建新线程消费
    pool.submitTask(std::make_shared<MyTask>((uLong)20000001, (uLong)30000000));    
    pool.submitTask(std::make_shared<MyTask>((uLong)20000001, (uLong)30000000));
    
    auto start = std::chrono::system_clock::now();
    uLong s1 = r1.get().cast_<uLong>();
    uLong s2 = r2.get().cast_<uLong>();
    uLong s3 = r3.get().cast_<uLong>();
    auto end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> d1 = end - start;

    std::cout << s1 + s2 + s3 << std::endl << d1.count() << std::endl;
    uLong sum = 0;
    start = std::chrono::system_clock::now();
    for(ulong i = 1; i <= (uLong)30000000; ++i) sum += i;
    end = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> d2 = end - start;
    std::cout << sum << std::endl << d2.count() << std::endl;
    return 0;
}
#endif

// int main()
// {
//     ThreadPool tp;
//     tp.start(4);
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     tp.submitTask(std::make_shared<MyTask>());
//     std::this_thread::sleep_for(std::chrono::seconds(20));

//     return 0;
// }